- Published on
领域驱动设计实践中如何组织代码
- Authors
- Name
- Qiu Yuzhou
以golang语言为例,介绍在领域驱动设计的开发的实现中如何组织代码。
模块化单体项目
界限上下文(Bounded Conetext)
分子目录/子包
上层结构按目录结构类似如下:
bounded-contexts/
├── account
├── asset
├── customer
├── invoice
├── payment
├── paymentv2
├── bookkeeping
├── historder
├── orderinsur
├── virtualphone
├── ...
界限上下文(Bounded Conetext)内分层架构
界限上下文(Bounded Conetext)
中参考分层架构(Layered Architecture)
和六边形架构(Hexagonal architecture pattern)
分子目录/子包。
account/
├── domain
├── app
├── adapters
├── entrypoints
将界限上下文(Bounded Conetext)
内的代码分为由内到外3层:
- 领域层,包含领域模型和领域服务
- 应用层,包含应用服务,也叫用例层
- 最外层,包含各种接口适配器。包括且不限于:数据库适配器、消息队列适配器、HTTP API适配器、gRPC适配器等
依赖与隔离
外层代码可以依赖内层和同层,内层不能依赖外层。 必要时使用接口以实现依赖反转。比如,领域层定义实体的持久化接口,在最外层接口实现中调用数据库SDK。
- 领域层仅包含领域逻辑,不包含任何外部依赖。
- 应用层包含应用逻辑,调用领域层。并且附加如身份验证、权限控制、操作审计等应用逻辑。
- 最外层包含外部依赖的适配器,如数据库的访问代码、消息队列的处理回调、HTTP API的实现、外部系统API调用等。
跨界限上下文(Bounded Conetext)
的代码依赖关系应该尽量减少,尽量通过事件驱动等方式实现。 总之,界限上下文中可以用数据库事务实现多个实体的一致性,跨界限上下文则通过事件实现最终一致性。 这样当随着项目长期迭代后,更容易将个别界限上下文拆分到独立的微服务项目中。